package com.factory.code.service.impl;

import com.factory.code.controller.vo.PageVO;
import com.factory.code.controller.vo.R;
import com.factory.code.repository.ProjectRepository;
import com.factory.code.repository.TemplateCustomRepository;
import com.factory.code.repository.TemplateRepository;
import com.factory.code.repository.ent.ProjectENT;
import com.factory.code.repository.ent.TemplateCustomENT;
import com.factory.code.repository.ent.TemplateENT;
import com.factory.code.service.ProjectService;
import com.factory.code.service.TemplateCustomService;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.Predicate;
import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class ProjectServiceImpl implements ProjectService {
    private static final Logger logger = LoggerFactory.getLogger(ProjectServiceImpl.class);

    @Autowired
    private ProjectRepository projectRepository;
    @Autowired
    private TemplateRepository templateRepository;
    @Autowired
    private TemplateCustomRepository templateCustomRepository;
    @Autowired
    private TemplateCustomService templateCustomService;

    @Value("${spring.datasource.url:8080}")
    private String dbUrl;
    @Value("${spring.datasource.username:root}")
    private String username;
    @Value("${spring.datasource.password:root}")
    private String password;


    @Override
    public List<ProjectENT> listAll() {
        return projectRepository.findAll();
    }

    @Override
    public PageVO<ProjectENT> getPage(Integer page, Integer limit, String name) {
        Sort.Direction sort = Sort.Direction.DESC;
        Pageable pageable = PageRequest.of(page, limit, sort, "id");
        Specification specification = (Specification) (root, criteriaQuery, cb) -> {
            //增加筛选条件
            Predicate predicate = cb.conjunction();
            if (StringUtils.isNotBlank(name)) {
                predicate.getExpressions().add(cb.like(root.get("name"), "%" + name + "%"));
            }
            return predicate;
        };
        Page<ProjectENT> pageList = projectRepository.findAll(specification, pageable);
        PageVO vo = new PageVO();
        vo.setTotal(pageList.getTotalElements());
        vo.setRecords(pageList.getContent());
        return vo;

    }

    @Override
    public ProjectENT getById(int projectId) {
        ProjectENT ent = projectRepository.getById(projectId);
        return ent;
    }

    @Override
    public R update(ProjectENT projectENT) {
        Integer samples = projectRepository.getSamplesById(projectENT.getId());
        if (samples != null && samples == 1) {
            return R.fail("示例不能操作");
        }

        projectRepository.saveAndFlush(projectENT);
        return R.ok();
    }

    @Override
    public R add(ProjectENT ent) {
        projectRepository.saveAndFlush(ent);
        return R.ok();

    }

    @Override
    @Transactional
    public R delete(ProjectENT projectENT) {
        Integer samples = projectRepository.getSamplesById(projectENT.getId());
        if (samples != null && samples == 1) {
            return R.fail("示例不能操作");
        }
        projectRepository.deleteById(projectENT.getId());
        templateRepository.deleteByProjectId(projectENT.getId());
        templateCustomRepository.deleteByProjectId(projectENT.getId());
        return R.ok();
    }

    @Override
    public R copy(int projectId) {
        ProjectENT ent = projectRepository.getById(projectId);
        ProjectENT newEnt = new ProjectENT();
        BeanUtils.copyProperties(ent, newEnt);
        newEnt.setName(newEnt.getName() + "-副本");
        newEnt.setId(null);
        newEnt.setSamples(0);
        newEnt.setCreateTime(new Date());
        projectRepository.saveAndFlush(newEnt);

        List<TemplateENT> templateENTList = templateRepository.findByProjectId(projectId);
        for (TemplateENT templateENT : templateENTList) {
            TemplateENT newTemplate = new TemplateENT();
            BeanUtils.copyProperties(templateENT, newTemplate);
            newTemplate.setId(null);
            newTemplate.setProjectId(newEnt.getId());
            newTemplate.setCreateTime(new Date());
            templateRepository.saveAndFlush(newTemplate);
        }
        List<TemplateCustomENT> customENTS = templateCustomService.listByProjectId(projectId);
        for (TemplateCustomENT customENT : customENTS) {
            TemplateCustomENT newCustomENT = new TemplateCustomENT();
            BeanUtils.copyProperties(customENT, newCustomENT);
            newCustomENT.setId(null);
            newCustomENT.setProjectId(newEnt.getId());
            newCustomENT.setCreateTime(new Date());
            templateCustomRepository.saveAndFlush(newCustomENT);
        }


        return null;
    }

    @Autowired
    JdbcTemplate jdbcTemplate;

    @Override
    public void initializeData() {
        try {

            ProjectENT projectENT = projectRepository.getById(1);
            List<String> list = new ArrayList<>();
            if (projectENT == null) {
                logger.info("[初始化数据]  数据库中：CodeFactory_示例 projectId=1 不存在执行sql");
                String path = "classpath:db" + File.separator + "init.sql";
                InputStream inputStream = getClass().getResourceAsStream("/db" + File.separator + "init.sql");
                for (String sql : IOUtils.readLines(inputStream, "utf-8")) {
                    if (StringUtils.isNotEmpty(sql) && sql.contains("INSERT INTO ")) {
                        list.add(sql);
                    }
                }
                for (String s : list) {
                    jdbcTemplate.update(s);
                    logger.info("[初始化数据]  创建数据 sql={}", s);
                }
                logger.info("[初始化数据] 完成");
                projectENT = projectRepository.getById(1);
            }
            if (projectENT != null) {
                projectENT.setDbUrl(dbUrl);
                projectENT.setDbUsername(username);
                projectENT.setDbPassword(password);
                projectENT.setName("CodeFactory_示例");
                projectRepository.saveAndFlush(projectENT);
            }
        } catch (Exception e) {
            logger.info("[初始化数据]  异常={}", e.getMessage());
        }
    }


}
